#ifdef RT_USE_OLD_CONN_WRAP

#include "RtBase.h"
#include "RtCnPkg.h"
#if !defined (_NEW_PROTO_TP)

///////////////////////////////////////////
//class CPkgConn
///////////////////////////////////////////
CPkgConn::CPkgConn(DWORD dwMaxSendBufLen) 
: CRtCnConn(dwMaxSendBufLen)
, m_needOnSend(FALSE)
{
	m_cType = CRtConnectionManager::CTYPE_PDU_PACKAGE;
	m_byConnType = CS_CONN_TYPE_PKG;

	m_bPkgNeedBuf = FALSE;	//Default no SendBuf for PKG

	m_pmbLocSendData = NULL;

	m_nUngetDataCnt = 0;

	m_bNoRoom = FALSE;

	m_bConnIndicate2Upper = FALSE;
}

CPkgConn::~CPkgConn()
{
	m_Timer.Cancel();
	Reset();
}

void CPkgConn::Reset()
{
	if(m_pmbLocSendData)
	{
		m_pmbLocSendData->DestroyChained();
		m_pmbLocSendData = NULL;
	}
	CRtCnConn::Reset();
}

RtResult CPkgConn::SetOption(
		DWORD aCommand, 
		LPVOID aArg)
{
	switch(aCommand) 
	{
	case CS_OPT_NEED_KEEPALIVE:
		m_bNeedKeepAlive = *static_cast<BOOL*>(aArg);
		return RT_OK;
	case CS_OPT_PKG_NEED_BUF:
		m_bPkgNeedBuf = *static_cast<BOOL*>(aArg);
		return RT_OK;
	default:
		return CRtCnConn::SetOption(aCommand, aArg);
	}
}

RtResult CPkgConn::GetOption(
		DWORD aCommand, 
		LPVOID aArg)
{
	RtResult rv = RT_ERROR_NOT_AVAILABLE;

	switch(aCommand)
	{
	case CS_OPT_NEED_KEEPALIVE:
		*(static_cast<BOOL*>(aArg)) = m_bNeedKeepAlive;
		return RT_OK;
		
	case CS_OPT_PKG_NEED_BUF:
		*(static_cast<BOOL*>(aArg)) = m_bPkgNeedBuf;
		return RT_OK;

	case RT_OPT_TRANSPORT_TRAN_TYPE:
		
		if(m_pITransport)
		{
			DWORD dwTransType;

			rv = m_pITransport->GetOption(
				RT_OPT_TRANSPORT_TRAN_TYPE, 
				(LPVOID)&dwTransType);

			if(RT_SUCCEEDED(rv))
			{
				if(m_bNeedKeepAlive)
					dwTransType |= CRtConnectionManager::CTYPE_PDU_KEEPALIVE;

				*(static_cast<CRtConnectionManager::CType*>(aArg)) 
				= CRtConnectionManager::CTYPE_PDU_PACKAGE | dwTransType;

				rv = RT_OK;
			}
		}
			
		return rv;
		
	default:
		return CRtCnConn::GetOption(aCommand, aArg);
	}
}

RtResult CPkgConn::SendDisconn(RtResult aReason)
{
	if(m_bPkgNeedBuf)
		return CRtCnConn::SendDisconn(aReason);

	if(m_wStatus != STATUS_DATA_CAN_SEND)
			return RT_ERROR_NOT_AVAILABLE;//Cannot send data now

	m_SendBuf.AddDisconnPDU(aReason);	
	SendDataFromSendBuf();
	return RT_OK;
}

void CPkgConn::OnSend(
					  IRtTransport *aTrptId,
					  CRtTransportParameter *aPara)
{
	if(m_bPkgNeedBuf)
	{
		CRtCnConn::OnSend(aTrptId, aPara);
		return;
	}

	RtResult rv = m_pITransport->SendData(*m_pmbLocSendData);
	if (RT_FAILED(rv))
		return;

	m_pmbLocSendData->DestroyChained();
	m_pmbLocSendData = NULL;

	if(m_needOnSend && m_pITransportSink)
	{
		m_needOnSend = FALSE;
		m_pITransportSink->OnSend(this, aPara);
	}
}

RtResult CPkgConn::SendData(
							CRtMessageBlock &aData, 
							CRtTransportParameter *aPara)
{ 
	if(m_wStatus != STATUS_DATA_CAN_SEND)
		return RT_ERROR_NOT_AVAILABLE;//Cannot send data now

	DWORD dataLen = aData.GetChainedLength();
	if (dataLen == 0)
	{
		RT_ERROR_TRACE_THIS("CPkgConn::SendData, dataLen should not be 0!");
		return RT_OK;
	}

	m_isDataSent = TRUE;

	if(m_bPkgNeedBuf)
			return CRtCnConn::SendData(aData, aPara);

// 	m_dwLastSendTick = GetTickCountEx();

	if (m_pmbLocSendData || m_needOnSend)
	{
		m_needOnSend = TRUE;
		return RT_ERROR_PARTIAL_DATA;
	}

	CRtCnPduData pd(
		FALSE, 
		0, 
		dataLen, 
		CS_PDU_TYPE_DATA_NORMAL, 
		NULL);
	
	CRtMessageBlock mb(pd.GetFixLength());
	pd.EncodeWithOutData(mb);
	mb.Append(&aData);

	RtResult rv = m_pITransport->SendData(mb);
	if (RT_FAILED(rv))
	{
		m_pmbLocSendData = mb.DuplicateChained();
	}

	return RT_OK;
}

void CPkgConn::SendRtt(DWORD inTimestamp)
{
	RT_ASSERTE_RETURN_VOID(!m_bPkgNeedBuf);

	CRtCnPduRtt rttPdu(inTimestamp);
	CRtMessageBlock mb(rttPdu.GetFixLength());
	rttPdu.Encode(mb);
	if (m_pmbLocSendData)
	{
		m_pmbLocSendData->Append(mb.DuplicateChained());
		return;
	}

	RtResult rv = m_pITransport->SendData(mb);
	if (RT_FAILED(rv))
	{
		m_pmbLocSendData = mb.DuplicateChained();
	}
}

RtResult CPkgConn::SendKeepAlive()
{
	if(m_bNeedKeepAlive)
	{
		if(m_bPkgNeedBuf)
			return CRtCnConn::SendKeepAlive();

		if(m_pmbLocSendData == NULL)
		{
			CRtCnPduKeepAlive KApdu;
			CRtMessageBlock mb(KApdu.GetFixLength());
			KApdu.Encode(mb);

			RtResult rv = m_pITransport->SendData(mb);
			if (RT_FAILED(rv))
			{
				m_pmbLocSendData = mb.DuplicateChained();
				RT_ERROR_TRACE_THIS("CPkgConn::SendKeepAlive, failed!");
				return rv;
			}
		}
	}

	return RT_OK;
}

RtResult CPkgConn::SendDataFromSendBuf()
{
	RtResult result = CRtCnConn::SendDataFromSendBuf();
	m_SendBuf.ClearAllSent();//Clear all buf have been sent

	if(m_pITransportSink && m_bNoRoom)
	{
		m_bNoRoom = FALSE;
		if(m_pITransportSink)
			m_pITransportSink->OnSend(this);
	}

	return result;
}
	
//void CPkgConn::ACK2PeerIfPossiable()
//{
//	//Do nothing, no ACK function
//	return;
//}

RtResult CPkgConn::Disconnect(RtResult aReason)
{
	RT_INFO_TRACE_THIS("CPkgConn::Disconnect(), aReason = " << aReason
		<< " m_wStatus=" << m_wStatus);
	m_Timer.Cancel();

	RtResult result = RT_OK;

//	CRtAutoPtr<CPkgConn> pTmpSvr(this);
	
	if(m_pITransport)
	{
		SendDisconn(aReason);
		result = m_pITransport->Disconnect(aReason);
		//m_pITransport = NULL;
	}

	SetCurrStatus(STATUS_UNCONNECTED);

	m_pITransportSink = NULL;
	
	return result;
}
///////////////////////////////////////////
//class CPkgConnClient
///////////////////////////////////////////
CPkgConnClient::CPkgConnClient() 
	: CPkgConn(SEND_BUF_LEN_MAX4PKG)
	, m_lastRtt(0)
{
	m_nConnReqCnt = 0;
	m_bConnRespRecved = FALSE;
	m_bConnectOnceMade = FALSE;
	m_bHandShakeCancelled = FALSE;

	m_pConnConnector = NULL;

	m_Timer.Schedule(this, CRtTimeValue(INTERVAL1,0));
	m_byInstanceType = CLIENT_INSTANCE;
}

CPkgConnClient::~CPkgConnClient()
{
}

void CPkgConnClient::OnConnectIndication(
											RtResult aReason,
											IRtTransport *aTrpt,
											IRtAcceptorConnectorId *aRequestId)
{
	RT_ASSERTE(m_pConnConnector->GetTPConnector() == aRequestId);

	if(m_bHandShakeCancelled)
	{
		//RT_INFO_TRACE_THIS("CPkgConnClient::OnConnectIndication(), connection has been cancelled.");
		if(aTrpt)
			aTrpt->Disconnect((RtResult)RT_OK);

		return;
	}
	
	m_pITransport = aTrpt;
	//Get Transport type
	DWORD dwTransType = CRtConnectionManager::CTYPE_NONE;
	if(m_pITransport)
		m_pITransport->GetOption(RT_OPT_TRANSPORT_TRAN_TYPE, (LPVOID)&dwTransType);
	m_cBaseType = dwTransType;

/*
	RT_INFO_TRACE_THIS("CPkgConnClient::OnConnectIndication(),"
		" m_pITransport = " << m_pITransport << 
		" aTrpt = " << aTrpt << 
		" m_cBaseType=" << m_cBaseType);
*/

	if(RT_SUCCEEDED(aReason))
	{
		m_pITransport = aTrpt;
		SetCurrStatus(STATUS_CONNECTED);//Physical connection make

		m_pITransport->OpenWithSink(this);

		SendConnReq();
	}
	else //There are errors, such as timeouted
	{
			//Callback to Upper layer
			m_pConnConnector->GetConnectorSink()->OnConnectIndication(
				aReason, 
				NULL, 
				m_pConnConnector);

			m_bConnIndicate2Upper = TRUE;
	}
}

void CPkgConnClient::OnDisconnect(
									 RtResult aReason,
									 IRtTransport *aTrptId)
{
	RT_INFO_TRACE_THIS("CPkgConnClient::OnDisconnect(), None Reconnection Disconnect, aReason="<<aReason);
	RT_ASSERTE(m_pITransport.Get() == aTrptId);
	
	m_Timer.Cancel();
	m_pITransport->Disconnect((RtResult)RT_ERROR_NETWORK_CONNECT_ERROR);
	//m_pITransport = NULL;
	
	//Callback 

	if(!m_bConnIndicate2Upper)
	{
		m_pConnConnector->GetConnectorSink()->OnConnectIndication(
			(RtResult)RT_ERROR_NETWORK_CONNECT_ERROR, 
			NULL, 
			m_pConnConnector);
		
		m_bConnIndicate2Upper = TRUE;
	}
	else
	{
		if(m_pITransportSink && STATUS_UNCONNECTED != m_wStatus)
			m_pITransportSink->OnDisconnect(aReason, this);
	}
	SetCurrStatus(STATUS_UNCONNECTED);
	m_pITransportSink = NULL;
}

void CPkgConnClient::OnTimer(CRtTimerWrapper* aId)
{
	if(m_wStatus == STATUS_CONNECTED || m_wStatus == STATUS_UNCONNECTED)//For Timer1 of waiting for ConnResp 
	{
//		RT_INFO_TRACE_THIS("CPkgConnClient::OnTimer(), haven't recv ConnResp PDU."
//			" m_cBaseType=" << m_cBaseType << 
//			" m_wStatus=" << m_wStatus);
		
		if(m_pConnReqPDU)
		{
			m_pConnReqPDU->DestroyChained();
			m_pConnReqPDU = NULL;
		}
		
		m_Timer.Cancel();//Cancel Timer1
		
		if(m_pITransport.Get())
			m_pITransport->Disconnect((RtResult)RT_ERROR_NETWORK_CONNECT_TIMEOUT);
		
		SetCurrStatus(STATUS_UNCONNECTED);
		
		//Callback to Upper layer
		if(!m_bConnIndicate2Upper)
		{
			m_pConnConnector->GetConnectorSink()->OnConnectIndication(
				(RtResult)RT_ERROR_NETWORK_CONNECT_TIMEOUT, 
				NULL, 
				m_pConnConnector);
			
			m_bConnIndicate2Upper = TRUE;
		}
		
		return;
		
	}
	else if(m_wStatus == STATUS_DATA_CAN_SEND)//For Timer2, Send & Check for Keep Alive PDU
	{
		RT_INFO_TRACE_THIS("CPkgConnClient::OnTimer, m_isDataReceived="<<m_isDataReceived<<" SINK="<<m_pITransportSink);
		if (m_pmbLocData)
		{
			RT_INFO_TRACE_THIS("recv buff size="<<m_pmbLocData->GetChainedLength());
		}
		LONGLONG dwCurrent = GetTickCountEx();
		SendRtt((DWORD)dwCurrent);
		if(m_bNeedKeepAlive)
		{
/*
			/// Don't need SendKeepAlive anymore, as SendRtt does the same work. 
			if (!m_isDataSent)
				SendKeepAlive();
			else
				m_isDataSent = FALSE;
*/

			if (!m_isDataReceived)
			{
				m_continuousIdleTime += m_keepAliveInterval;
				if (m_continuousIdleTime>=SERVER_UNAVAIL_TIMEOUT)
				{
					RT_WARNING_TRACE_THIS("CPkgConnClient::OnTimer, connection idle timeout! time="<<m_continuousIdleTime);

					m_Timer.Cancel();//Cancel Timer2
					
					SetCurrStatus(STATUS_UNCONNECTED);
					
					m_pITransport->Disconnect((RtResult)RT_ERROR_NETWORK_CONNECT_ERROR);
					
					//Callback 
					if(m_pITransportSink)
						m_pITransportSink->OnDisconnect((RtResult)RT_ERROR_NETWORK_CONNECT_ERROR, this);

					m_pITransportSink = NULL;
				}
			}
			else
			{
				m_continuousIdleTime = 0;
				m_isDataReceived = FALSE;
			}
		}
	}
}

void CPkgConnClient::SetConnConnector(CPkgConnConnector* pConnConnector)
{
	m_pConnConnector = pConnConnector;
}

void CPkgConnClient::CancelHandShake()
{
	//While handshaking
	if(!m_bConnectOnceMade)
	{
		if(m_pITransport)
			m_pITransport->Disconnect((RtResult)RT_OK);
		
		m_bHandShakeCancelled = TRUE;
	}
}

void CPkgConnClient::OnRecvConnResp()
{
	if(m_bHandShakeCancelled)//do nothing
	{
		RT_INFO_TRACE_THIS("CPkgConnClient::OnRecvConnResp(), connection has been cancelled.");
		m_Timer.Cancel();
		if(m_pITransport)
			m_pITransport->Disconnect((RtResult)RT_OK);
		
		return;
	}

	if(!m_bConnRespRecved)
	{
		m_bConnRespRecved = TRUE;
		m_Timer.Cancel();
		
		//Get the channel number from ConnRespPDU
		CRtCnPduConnReqResp presp;
		presp.Decode(*m_pmbLocData);
		WORD wChannel = presp.GetConTag();
		BYTE byConnType = presp.GetConnType();

		if(byConnType != m_byConnType)//Wrong type connection
		{
			RT_INFO_TRACE_THIS("CPkgConnClient::OnRecvConnResp(), Wrong connection type");
			Disconnect((RtResult)RT_ERROR_NETWORK_CONNECTION_WRONG_TYPE);
			
			//Callback to Upper layer
			m_pConnConnector->GetConnectorSink()->OnConnectIndication(
				(RtResult)RT_ERROR_NETWORK_CONNECTION_WRONG_TYPE, 
				NULL, 
				m_pConnConnector);

			m_bConnIndicate2Upper = TRUE;
			
			SetCurrStatus(STATUS_UNCONNECTED);
			
			return;
		}
		
		RT_INFO_TRACE_THIS("CPkgConnClient::OnRecvConnResp(), wChannel = " << presp.GetConTag());
		
		m_wChannel = wChannel;
		//Callback ITcpRlbConnSink::OnConnect(..),Indicate upper layer can send data now.
		SetCurrStatus(STATUS_DATA_CAN_SEND);
// 		SendRtt((DWORD)GetTickCountEx());
		m_bConnectOnceMade = TRUE;
		m_pConnConnector->GetConnectorSink()->OnConnectIndication(
			(RtResult)RT_OK, 
			this, 
			m_pConnConnector);

		m_bConnIndicate2Upper = TRUE;
		
		m_nConnReqCnt = 0;//Reset the counter
		//Destroy Connection Request PDU in m_pConnReqPDU
		m_pConnReqPDU->DestroyChained();
		m_pConnReqPDU = NULL;
		//Re-schedule the Timer1 switch to Timer2;
		m_Timer.Schedule(this, CRtTimeValue(m_keepAliveInterval,0), 0);
		
		/* No OnSend Now
		//Indicate upper layer can send data
		if(m_pITransportSink)
		{
			RT_INFO_TRACE_THIS("CPkgConnClient::OnRecvConnResp(), OnSend()");
			m_pITransportSink->OnSend(this);
		}
		*/

	}
	else
	{
		//RT_INFO_TRACE_THIS("CPkgConnClient::OnRecvConnResp(), Already received RESP PDU");
		m_pmbLocData->AdvanceChainedReadPtr(
			CRtCnPduBase::GetFixLength(CS_PDU_TYPE_CONN_RESP));
	}
}

//Client using
void CPkgConnClient::OnRecvDisconn()
{
	//Get reason from Disconn PDU
	CRtCnPduDisconn pdc;
	CRtMessageBlock mb(pdc.GetFixLength());
	pdc.Decode(*m_pmbLocData);

	WORD wReason = pdc.GetReason();
	RT_INFO_TRACE_THIS("CPkgConnClient::OnRecvDisconn(), Normal disconnect, wReason = " << wReason);

	RtResult aReason = (RtResult)wReason;
	
	m_Timer.Cancel();
	SetCurrStatus(STATUS_UNCONNECTED);

	//Get Transport type
	DWORD dwTransType;

	if(m_pITransport)
		m_pITransport->GetOption(RT_OPT_TRANSPORT_TRAN_TYPE, (LPVOID)&dwTransType);
	
	//UDP will not get OnDisconnect(...) callback, so OnDisconnect to upper layer now
//	if(RT_BIT_ENABLED(dwTransType, CRtConnectionManager::CTYPE_UDP))
	{
		if(m_pITransportSink)
			m_pITransportSink->OnDisconnect(aReason, this);//Network error, Callback to Upper layer
	}

	//TCP will get OnDisconnect(..) callback later
}

void CPkgConnClient::OnRecvRtt(DWORD inTimestamp)
{
	DWORD rtt = ((DWORD)GetTickCountEx()) - inTimestamp;
	if ( rtt>=50 &&
		( rtt>1000 || (rtt>m_lastRtt && rtt-m_lastRtt>m_lastRtt/5) || (rtt<m_lastRtt && m_lastRtt-rtt>m_lastRtt/5) ) )
	{
		RT_INFO_TRACE_THIS("CPkgConnClient::OnRecvRtt, rtt="<<rtt
			<<" BuffSize="<<(m_pmbLocSendData?m_pmbLocSendData->GetChainedLength():0) );
		m_lastRtt = rtt;
	}
}

///////////////////////////////////////////
//class CPkgConnServer
///////////////////////////////////////////
CPkgConnServer::CPkgConnServer() 
	: CPkgConn(SEND_BUF_LEN_MAX4PKG)
{
	m_pSvrList = NULL;
	m_pConnAcceptor = NULL;

//	m_disconn_timestamp = CRtTimeValue::GetTimeOfDay();
	m_byInstanceType = SERVER_INSTANCE;

//	m_bConnReqRecved = FALSE;
}

CPkgConnServer::~CPkgConnServer()
{
	//RT_INFO_TRACE_THIS("CPkgConnServer::~CPkgConnServer");
	if(m_pITransport)
		m_pITransport->Disconnect(RT_OK);

	m_Timer.Cancel();
	Reset();
}

void CPkgConnServer::Reset()
{
	m_pSvrList = NULL;
	m_pConnAcceptor = NULL;

	//m_disconn_timestamp = CRtTimeValue::GetTimeOfDay();

	CPkgConn::Reset();
}

void CPkgConnServer::OnDisconnect(
									 RtResult aReason,
									 IRtTransport *aTrptId)
{
//	if(m_wStatus == STATUS_UNCONNECTED)
//		return;

	RT_INFO_TRACE_THIS("CPkgConnServer::OnDisconnect(), aReason = " << aReason 
		<< ", aTrptId = " << aTrptId << " m_wStatus=" << m_wStatus);
	RT_ASSERTE(m_pITransport.Get() == aTrptId);
	
//	CRtAutoPtr<CPkgConnServer> pTmpSvr(this);

	m_Timer.Cancel();

	m_pITransport->Disconnect((RtResult)RT_ERROR_NETWORK_CONNECT_ERROR);
	if(m_pITransportSink && m_wStatus == STATUS_DATA_CAN_SEND)
	{
		m_pITransportSink->OnDisconnect(aReason, this);//Network error, Callback to Upper layer
	}
	SetCurrStatus(STATUS_UNCONNECTED);

	m_pITransportSink = NULL;
}
	
void CPkgConnServer::OnTimer(CRtTimerWrapper* aId)
{
	if(aId == &m_ReleaseTimer)//release time;
	{
		RT_INFO_TRACE_THIS("CPkgConnServer::OnTimer, m_ReleaseTimer,"
			" ref=" << GetReference() << 
			" m_wStatus=" << m_wStatus);
		RT_ASSERTE(GetReference() == 0);
		
		CRtAutoPtr<CPkgConnServer> pTmpPkgSvr(this);
		//m_pITransport->Disconnect((RtResult)RT_ERROR_NETWORK_CONNECT_ERROR);
		SetCurrStatus(STATUS_UNCONNECTED);
		return;
	}

	//keepalive time;
	RT_ASSERTE(m_bNeedKeepAlive);
	if (m_wStatus != STATUS_DATA_CAN_SEND)
		return;
	
	if (!m_isDataSent)
		SendKeepAlive();
	else
		m_isDataSent = FALSE;

	if (!m_isDataReceived)
	{
		m_continuousIdleTime += m_keepAliveInterval;
		if (m_continuousIdleTime>=SERVER_UNAVAIL_TIMEOUT)
		{
			RT_WARNING_TRACE_THIS("CPkgConnServer::OnTimer, connection idle timeout! time="<<m_continuousIdleTime);

			m_Timer.Cancel();//Cancel Timer2
			
			SetCurrStatus(STATUS_UNCONNECTED);
			
			m_pITransport->Disconnect((RtResult)RT_ERROR_NETWORK_CONNECT_ERROR);
			
			//Callback 
			if(m_pITransportSink)
				m_pITransportSink->OnDisconnect((RtResult)RT_ERROR_NETWORK_CONNECT_ERROR, this);

			m_pITransportSink = NULL;
		}
	}
	else
	{
		m_continuousIdleTime = 0;
		m_isDataReceived = FALSE;
	}
}

void CPkgConnServer::OnConnectIndication(
											RtResult aReason,
											IRtTransport *aTrpt,
											IRtAcceptorConnectorId *aRequestId)
{
	RT_ASSERTE(m_pConnAcceptor->GetTPAcceptor() == aRequestId);

	m_ReleaseTimer.Schedule(this, CRtTimeValue(TV_FOR_RELEASE, 0), 1);

	m_pITransport = aTrpt;

	aTrpt->OpenWithSink(this);
	
	SetCurrStatus(STATUS_CONNECTED);

	//m_bConnReqRecved = FALSE;//waiting for new connection coming

	//Get Transport type
	DWORD dwTransType = CRtConnectionManager::CTYPE_NONE;

	if(m_pITransport)
		m_pITransport->GetOption(RT_OPT_TRANSPORT_TRAN_TYPE, (LPVOID)&dwTransType);

	m_cBaseType = dwTransType;
}

CRtTimeValue CPkgConnServer::GetDisconnTimestamp()
{
	return m_disconn_timestamp;
}

void CPkgConnServer::SetServerList(CPkgConnServerList *pSvrList)
{
	m_pSvrList = pSvrList;
}

void CPkgConnServer::SetConnAcceptor(CPkgConnAcceptor* pConnAcceptor)
{
	m_pConnAcceptor = pConnAcceptor;
}

void CPkgConnServer::OnRecvConnReq()
{
	//Get wChannel from PDU
	CRtCnPduConnReqResp preq;
	preq.Decode(*m_pmbLocData);

	BYTE byConnType = preq.GetConnType();

	if(byConnType != m_byConnType  && byConnType != CS_CONN_TYPE_RLB)//Wrong Connection type
	{
		RT_INFO_TRACE_THIS("CPkgConnServer::OnRecvConnReq(), Wrong Connection type="<<byConnType<<",m_byConnType="<<m_byConnType<<", m_wStatus="<<m_wStatus);
		SendConnResp();//Send back with my ConnType for wrong type indication

		Disconnect(RT_ERROR_NOT_AVAILABLE);

		return;
	}
	else if(byConnType == CS_CONN_TYPE_RLB)
	{
		//CRtAutoPtr<CPkgConnServer> pTmpPkgSvr(this);
		CRlbConnTCPServer* pSvr = new CRlbConnTCPServer();				
		pSvr->NeedKeepAlive(TRUE);
		pSvr->SetConnAcceptor((CConnAcceptorT<class CRlbConnTCPServer> *)m_pConnAcceptor.ParaIn());
		pSvr->SetServerList((ServerListT<class CRlbConnTCPServer> *)m_pSvrList);
		pSvr->OnConnectIndication(RT_OK, m_pITransport.ParaIn(), m_pConnAcceptor.Get());
		pSvr->OnRecvConnReq(preq);
		CRtMessageBlock *pTmp = m_pmbLocData->Disjoint(0);
		if(pTmp && pTmp->GetChainedLength())
		{
			pSvr->OnReceive(*pTmp, m_pITransport.ParaIn(), NULL);
		}
		m_pmbLocData->DestroyChained();
		m_pmbLocData = NULL;
		m_pITransport = NULL;
		return;
	}

	if(m_wStatus == STATUS_CONNECTED)//first getting ConnReq PDU
	{
		RT_INFO_TRACE_THIS("CPkgConnServer::OnRecvConnReq(), New connection coming"
			" byConnType=" << byConnType << 
			" m_cBaseType=" << m_cBaseType);

		m_pConnAcceptor->GetAcceptorSink()->OnConnectIndication(
			(RtResult)RT_OK, 
			this, 
			m_pConnAcceptor.Get());

		m_bConnIndicate2Upper = TRUE;
		SendConnResp();
		SetCurrStatus(STATUS_DATA_CAN_SEND);
		
		if(m_bNeedKeepAlive)
		{
			LONG lKAInterval = (LONG)m_keepAliveInterval;
			m_Timer.Schedule(this, CRtTimeValue(lKAInterval, 0));
		}
		
		m_ReleaseTimer.Cancel();
	}
	else if(m_wStatus == STATUS_DATA_CAN_SEND)
	{
		SendConnResp();
	}
	else
	{
		RT_ERROR_TRACE_THIS("CPkgConnServer::OnRecvConnReq, WRONG status, m_wStatus="<<m_wStatus);
//		Disconnect(RT_ERROR_NOT_AVAILABLE);
		RT_ASSERTE(FALSE);
	}
}

void CPkgConnServer::OnRecvRtt(DWORD inTimestamp)
{
	SendRtt(inTimestamp);
}

#endif

#endif // RT_USE_OLD_CONN_WRAP
